package com.bwie.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bwie.mapper.TbOrderDetailMapper;
import com.bwie.mapper.TbOrderRecordMapper;
import com.bwie.mapper.TbProdInfoMapper;
import com.bwie.poi.ExcelUtil;
import com.bwie.pojo.TbOrder;
import com.bwie.pojo.TbOrderDetail;
import com.bwie.pojo.TbOrderRecord;
import com.bwie.pojo.TbProdInfo;
import com.bwie.service.TbOrderService;
import com.bwie.mapper.TbOrderMapper;
import com.bwie.utils.R;
import com.bwie.utils.TokenUtils;
import com.bwie.vo.PageInfoVo;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
* @author 31803
* @description 针对表【tb_order(订单表)】的数据库操作Service实现
* @createDate 2025-06-20 15:27:20
*/
@Service
public class TbOrderServiceImpl extends ServiceImpl<TbOrderMapper, TbOrder>
    implements TbOrderService{

    @Autowired
    TbOrderMapper tbOrderMapper;
    @Autowired
    TbProdInfoMapper tbProdInfoMapper;

    @Autowired
    HttpServletRequest request;

    @Autowired
    TbOrderRecordMapper tbOrderRecordMapper;

    @Autowired
    TbOrderDetailMapper tbOrderDetailMapper;

    @Autowired
    RedissonClient redissonClient;

    @Autowired
    HttpServletResponse response;

    @Autowired
    StringRedisTemplate redisTemplate;


    @Override
    public R GetOrderList(PageInfoVo pageInfoVo) {
        //1构造分页参数
        Page<TbOrder> page = new Page<>(pageInfoVo.getPageNum(), pageInfoVo.getPageSize());
        //2获取查询分页数据
        QueryWrapper<TbOrder> wrapper = new QueryWrapper<>();
        //根据订单商品名称迷糊查询和订单id精确查询
        if(StringUtils.isNotEmpty(pageInfoVo.getKeyWord())){
            wrapper.lambda().like(TbOrder::getProdInfo,pageInfoVo.getKeyWord())
                    .or()
                    .eq(TbOrder::getOrderId,pageInfoVo.getKeyWord());
        }
        //根据订单状态精确查询
        if(pageInfoVo.getStatusId()!=null){
            wrapper.lambda().eq(TbOrder::getOrderStatus,pageInfoVo.getStatusId());
        }
        //根据订单类型精确查询
        if(pageInfoVo.getTypeId()!=null){
            wrapper.lambda().eq(TbOrder::getOrderType,pageInfoVo.getTypeId());
        }
        wrapper.lambda().orderByDesc(TbOrder::getOrderId);

        Page<TbOrder> tbOrderPage = tbOrderMapper.selectPage(page, wrapper);
        List<TbOrder> tbOrders = tbOrderPage.getRecords();
        for (TbOrder tbOrder : tbOrders) {
            List<String> orderImageList = tbOrderMapper.getOrderImageList(tbOrder.getOrderId());
            ArrayList<String> list = new ArrayList<>();
            if(orderImageList!=null&&orderImageList.size()>0){
                for (String s : orderImageList) {
                    if(s!=null&&!s.equals("")){
                        List<String> strings = JSON.parseArray(s, String.class);
                        list.addAll(strings);
                    }
                }
            }
            tbOrder.setImageList(list);
        }
        String token = request.getHeader("token");
        if(token==null){
            return R.erorr().setMsg("用户未登录");
        }
        Integer userId = TokenUtils.getUserId(token);
        //在数据返回之前把前端的列表存入缓存
        String key ="order-list"+userId;
        redisTemplate.opsForValue().set(key,JSON.toJSONString(tbOrderPage.getRecords()));

        return R.ok().setData(tbOrderPage);

    }

    @Override
    public R getProdInfoList() {

        List<TbProdInfo> tbProdInfos = tbProdInfoMapper.selectList(null);

        return R.ok().setData(tbProdInfos);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R addOrder(List<TbProdInfo> tbProdInfos) {

        String token = request.getHeader("token");
        if(token==null){
            return R.erorr().setMsg("token不存在请登录");
        }
        String userName = TokenUtils.getUserName(token);
        Integer userId = TokenUtils.getUserId(token);

        BigDecimal totalAmount = new BigDecimal("0");
        StringBuilder prodNames=new StringBuilder();

        //1扣减库存
        RLock lock = redissonClient.getLock("order-lock");
        try {
            //上锁
            lock.lock();
            //添加分布式锁防止超卖
            for (TbProdInfo tbProdInfo : tbProdInfos) {
                TbProdInfo ProdInfo = tbProdInfoMapper.selectById(tbProdInfo.getInfoId());
                if(tbProdInfo.getBuyNum()>ProdInfo.getProdStock()){
                    throw new RuntimeException("库存不足");
                }
                ProdInfo.setProdStock(ProdInfo.getProdStock()-tbProdInfo.getBuyNum());
                //修改商品库存
                tbProdInfoMapper.updateById(ProdInfo);
                totalAmount=totalAmount.add(tbProdInfo.getProdPrice().multiply(BigDecimal.valueOf(tbProdInfo.getBuyNum())));
                if(prodNames.length()>0){
                    prodNames.append(",");
                    prodNames.append(tbProdInfo.getProdName());
                }else{
                    prodNames.append(tbProdInfo.getProdName());
                }

            }
        }
        finally {
            //解锁
            lock.unlock();
        }


        //2添加订单
        TbOrder tbOrder = new TbOrder();
        tbOrder.setOrderAmount(totalAmount);
        //调用雪花算法生成ID
        long l = IdUtil.getSnowflake(1, 1).nextId();
        tbOrder.setOrderNo(""+l);
        tbOrder.setOrderStatus(0);
        tbOrder.setOrderType(1);
        tbOrder.setPayTime(new Date());
        tbOrder.setProdInfo(prodNames.toString());
        tbOrder.setCreateTime(new Date());
        tbOrder.setCreateBy(userName);
        tbOrder.setUserId(userId);
        tbOrderMapper.insert(tbOrder);
        //3添加订单详细
        for (TbProdInfo tbProdInfo : tbProdInfos) {
            TbOrderDetail tbOrderDetail = new TbOrderDetail();
            tbOrderDetail.setOrderId(tbOrder.getOrderId());
            tbOrderDetail.setBuyPrice(tbProdInfo.getProdPrice());
            tbOrderDetail.setInfoId(tbProdInfo.getInfoId());
            tbOrderDetail.setBuyNum(tbProdInfo.getBuyNum());
            tbOrderDetail.setProdId(tbProdInfo.getProdId());
            tbOrderDetail.setCreateBy(userName);
            tbOrderDetail.setCreateTime(new Date());
            tbOrderDetailMapper.insert(tbOrderDetail);
        }
        //4添加订单记录
        TbOrderRecord tbOrderRecord = new TbOrderRecord();
        tbOrderRecord.setOrderId(tbOrder.getOrderId());
        tbOrderRecord.setOptRecord("用户添加订单");
        tbOrderRecord.setCreateTime(new Date());
        tbOrderRecord.setCreateBy(userName);
        tbOrderRecordMapper.insert(tbOrderRecord);

        return R.ok();
    }

    @Override
    public void exportOrderList(Integer userId) {
        //1调用导出文件
        ExcelUtil<TbOrder> excelUtil = new ExcelUtil<TbOrder>(TbOrder.class);
        //在数据返回之前把前端的列表存入缓存
        String key ="order-list"+userId;
        String s = redisTemplate.opsForValue().get(key);
        List<TbOrder> tbOrderList = JSON.parseArray(s, TbOrder.class);
        //2导出excel文件
        excelUtil.exportExcel(response,tbOrderList,"订单列表");
    }

    @Override
    public R deleteOrderBatch(List<Integer> ids) {
        //校验ids是否为空
        if(ids==null||ids.size()==0){
            return R.erorr().setMsg("请选择数据");
        }
        //删除订单
        tbOrderMapper.deleteBatchIds(ids);

        //删除订单详情表
        for (Integer id : ids) {
            tbOrderDetailMapper.deleteById(id);
        }

        return R.ok();
    }
}




